package com.tbynet.jwp.repository.spi;

import com.jfinal.plugin.activerecord.Page;
import com.tbynet.jwp.framework.core._JwpService;
import com.tbynet.jwp.model.Terms;

import java.util.List;
import java.util.Map;

/**
 * 分类项服务接口 - 基于WordPress 4.9分类系统设计
 * 负责分类项和分类法的完整生命周期管理
 *
 * @author 佰亿互联
 * @version 1.0
 * @since 2025-11-04
 */
public interface TermService extends _JwpService<Terms> {

    public Terms getTerm(Object termId, String taxonomy);
    public Terms getTerm(Object objectId, Object termTaxonomyId, String taxonomy);
    public List<Terms> getTerms(String taxonomy);
    public List<Terms> getTerms(String taxonomy, String q);
    public Map<String, List<Terms>> getParents(String taxonomy);
    public List<Terms> getTerms(Object objectId, String taxonomy);
    public Page<Terms> search(int pageNumber, int pageSize, String taxonomy, String q);

    // ============ 分类项基础操作 ============

    /**
     * 根据分类项ID获取完整分类项信息（包含分类法信息）
     *
     * @param termId 分类项ID
     * @return 分类项对象，包含分类法信息
     */
    Terms getTermWithTaxonomy(Object termId);

    /**
     * 根据分类项别名获取分类项
     *
     * @param slug 分类项别名
     * @return 分类项对象
     */
    Terms getTermBySlug(String slug);

    /**
     * 根据名称和分类法获取分类项
     *
     * @param name 分类项名称
     * @param taxonomy 分类法
     * @return 分类项对象
     */
    Terms getTermByNameAndTaxonomy(String name, String taxonomy);

    /**
     * 根据别名和分类法获取分类项
     *
     * @param slug 分类项别名
     * @param taxonomy 分类法
     * @return 分类项对象
     */
    Terms getTermBySlugAndTaxonomy(String slug, String taxonomy);

    // ============ 分类法相关操作 ============

    /**
     * 获取所有分类法列表
     *
     * @return 分类法列表
     */
    List<String> getTaxonomies();

    /**
     * 根据分类法获取分类项列表
     *
     * @param taxonomy 分类法
     * @return 分类项列表
     */
    List<Terms> getTermsByTaxonomy(String taxonomy);

    /**
     * 根据分类法获取分类项列表（包含层级关系）
     *
     * @param taxonomy 分类法
     * @param hierarchical 是否包含层级关系
     * @return 分类项列表
     */
    List<Terms> getTermsByTaxonomy(String taxonomy, boolean hierarchical);

    /**
     * 根据分类法和父级ID获取子分类项
     *
     * @param taxonomy 分类法
     * @param parentId 父级分类项ID
     * @return 子分类项列表
     */
    List<Terms> getChildTerms(String taxonomy, Object parentId);

    /**
     * 获取顶级分类项（parent_id为0）
     *
     * @param taxonomy 分类法
     * @return 顶级分类项列表
     */
    List<Terms> getTopLevelTerms(String taxonomy);

    // ============ 对象关联查询 ============

    /**
     * 根据对象ID和分类法获取关联的分类项
     *
     * @param objectId 对象ID（如文章ID）
     * @param taxonomy 分类法
     * @return 分类项列表
     */
    List<Terms> getTermsByObject(Object objectId, String taxonomy);

    /**
     * 根据对象ID获取所有关联的分类项
     *
     * @param objectId 对象ID
     * @return 分类项列表
     */
    List<Terms> getTermsByObject(Object objectId);

    /**
     * 检查对象是否有关联的分类项
     *
     * @param objectId 对象ID
     * @param termId 分类项ID
     * @return 是否关联
     */
    boolean hasTerm(Object objectId, Object termId);

    /**
     * 为对象设置分类项关联
     *
     * @param objectId 对象ID
     * @param termIds 分类项ID数组
     * @param taxonomy 分类法
     * @return 是否成功
     */
    boolean setObjectTerms(Object objectId, Object[] termIds, String taxonomy);

    /**
     * 为对象添加分类项关联
     *
     * @param objectId 对象ID
     * @param termId 分类项ID
     * @param taxonomy 分类法
     * @return 是否成功
     */
    boolean addObjectTerm(Object objectId, Object termId, String taxonomy);

    /**
     * 移除对象与分类项的关联
     *
     * @param objectId 对象ID
     * @param termId 分类项ID
     * @return 是否成功
     */
    boolean removeObjectTerm(Object objectId, Object termId);

    // ============ 标签相关操作 ============

    /**
     * 获取所有标签
     *
     * @return 标签列表
     */
    List<Terms> getTags();

    /**
     * 根据文章ID获取标签
     *
     * @param postId 文章ID
     * @return 标签列表
     */
    List<Terms> getTagsByPostId(Object postId);

    /**
     * 搜索标签
     *
     * @param pageNumber 页码
     * @param pageSize 每页大小
     * @param keyword 关键词
     * @return 标签分页结果
     */
    Page<Terms> searchTags(int pageNumber, int pageSize, String keyword);

    /**
     * 获取热门标签（按使用次数排序）
     *
     * @param limit 返回数量
     * @return 热门标签列表
     */
    List<Terms> getPopularTags(int limit);

    // ============ 分类目录相关操作 ============

    /**
     * 获取所有分类目录
     *
     * @return 分类目录列表
     */
    List<Terms> getCategories();

    /**
     * 根据文章ID获取分类目录
     *
     * @param postId 文章ID
     * @return 分类目录列表
     */
    List<Terms> getCategoriesByPostId(Object postId);

    /**
     * 获取默认分类目录
     *
     * @return 默认分类目录
     */
    Terms getDefaultCategory();

    // ============ 层级关系操作 ============

    /**
     * 获取分类项的父级分类项
     *
     * @param termId 分类项ID
     * @return 父级分类项
     */
    Terms getParentTerm(Object termId);

    /**
     * 获取分类项的所有祖先分类项（从根到直接父级）
     *
     * @param termId 分类项ID
     * @return 祖先分类项列表
     */
    List<Terms> getAncestorTerms(Object termId);

    /**
     * 获取分类项的所有子孙分类项
     *
     * @param termId 分类项ID
     * @return 子孙分类项列表
     */
    List<Terms> getDescendantTerms(Object termId);

    /**
     * 获取分类树形结构
     *
     * @param taxonomy 分类法
     * @return 树形结构的分类项映射
     */
    Map<Long, List<Terms>> getTermTree(String taxonomy);

    // ============ 搜索和过滤 ============

    /**
     * 根据分类法和关键词搜索分类项
     *
     * @param taxonomy 分类法
     * @param keyword 关键词
     * @return 分类项列表
     */
    List<Terms> searchTerms(String taxonomy, String keyword);

    /**
     * 高级搜索分类项
     *
     * @param pageNumber 页码
     * @param pageSize 每页大小
     * @param taxonomy 分类法
     * @param keyword 关键词
     * @param parentId 父级ID（可选）
     * @return 分类项分页结果
     */
    Page<Terms> search(int pageNumber, int pageSize, String taxonomy, String keyword, Object parentId);

    /**
     * 获取空分类项（没有关联对象的分类项）
     *
     * @param taxonomy 分类法
     * @return 空分类项列表
     */
    List<Terms> getEmptyTerms(String taxonomy);

    // ============ 检查和验证 ============

    /**
     * 检查分类项名称在指定分类法中是否唯一
     *
     * @param name 分类项名称
     * @param taxonomy 分类法
     * @param excludeTermId 排除的分类项ID（用于更新操作）
     * @return 是否唯一
     */
    boolean isTermNameUnique(String name, String taxonomy, Object excludeTermId);

    /**
     * 检查分类项别名是否唯一
     *
     * @param slug 分类项别名
     * @param taxonomy 分类法
     * @param excludeTermId 排除的分类项ID
     * @return 是否唯一
     */
    boolean isTermSlugUnique(String slug, String taxonomy, Object excludeTermId);

    /**
     * 检查分类项是否有子分类项
     *
     * @param termId 分类项ID
     * @return 是否有子分类项
     */
    boolean hasChildTerms(Object termId);

    /**
     * 检查分类项是否被对象使用
     *
     * @param termId 分类项ID
     * @return 是否被使用
     */
    boolean isTermInUse(Object termId);

    /**
     * 检查分类项是否有其他分类法
     *
     * @param termId 分类项ID
     * @param excludeTaxonomy 排除的分类法
     * @return 是否有其他分类法
     */
    boolean hasOtherTaxonomy(Object termId, String excludeTaxonomy);

    // ============ 统计操作 ============

    /**
     * 获取分类项下的对象数量
     *
     * @param termId 分类项ID
     * @return 对象数量
     */
    long getTermCount(Object termId);

    /**
     * 根据分类法获取分类项数量
     *
     * @param taxonomy 分类法
     * @return 分类项数量
     */
    long getTermCountByTaxonomy(String taxonomy);

    /**
     * 更新分类项计数
     *
     * @param termId 分类项ID
     * @return 是否成功
     */
    boolean updateTermCount(Object termId);

    // ============ 工具方法 ============

    /**
     * 根据名称获取或创建分类项
     *
     * @param name 分类项名称
     * @param taxonomy 分类法
     * @return 分类项对象
     */
    Terms getOrCreateTerm(String name, String taxonomy);

    /**
     * 根据名称获取或创建分类项（指定父级）
     *
     * @param name 分类项名称
     * @param taxonomy 分类法
     * @param parentId 父级分类项ID
     * @return 分类项对象
     */
    Terms getOrCreateTerm(String name, String taxonomy, Object parentId);

    /**
     * 生成唯一的分类项别名
     *
     * @param name 分类项名称
     * @param taxonomy 分类法
     * @return 唯一的别名
     */
    String generateUniqueSlug(String name, String taxonomy);

    /**
     * 清理未使用的分类项
     *
     * @param taxonomy 分类法
     * @return 清理的数量
     */
    int cleanupUnusedTerms(String taxonomy);

    // ============ 批量操作 ============

    /**
     * 批量更新分类项计数
     *
     * @param termIds 分类项ID列表
     * @return 成功更新的数量
     */
    int batchUpdateTermCounts(List<Object> termIds);

    /**
     * 批量删除分类项
     *
     * @param termIds 分类项ID列表
     * @param force 是否强制删除（即使有对象关联）
     * @return 成功删除的数量
     */
    int batchDeleteTerms(List<Object> termIds, boolean force);
}